package com.binance.notification.web.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.FileCopyUtils;

import com.binance.master.utils.StringUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class I18nUtils {

    private static final Map<String, Resource> resourceMap = Maps.newHashMap();
    static {
        PathMatchingResourcePatternResolver pmrpr = new PathMatchingResourcePatternResolver();
        Resource[] resources;
        try {
            resources = pmrpr
                    .getResources(PathMatchingResourcePatternResolver.CLASSPATH_URL_PREFIX + "notification-i18n/*");
        } catch (IOException e) {
            log.error("获取国际化资源错误", e);
            throw new IllegalArgumentException(e);
        }
        for (Resource res : resources) {
            String fileName = res.getFilename();
            String language = StringUtils.substringBetween(fileName, "notification.", ".prop");
            resourceMap.put(language, res);
        }
    }

    public static byte[] getI18nResources() throws Exception {
        Path dir = Files.createTempDirectory(null);
        List<Path> targets = Lists.newArrayList();
        for (Map.Entry<String, Resource> entry : resourceMap.entrySet()) {
            Resource res = entry.getValue();
            String fileName = res.getFilename();
            Path target = dir.resolve(fileName);
            target = Files.createFile(target);
            try (InputStream in = res.getInputStream()) {
                Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
            }
            targets.add(target);
        }
        String zipName = "resources.zip";
        Path zipPath = compress(zipName, dir, targets);
        byte[] buf = new byte[0];
        try (InputStream in = Files.newInputStream(zipPath, StandardOpenOption.READ)) {
            buf = FileCopyUtils.copyToByteArray(in);
        }
        deleteFile(dir.toFile());
        return buf;
    }

    private static void deleteFile(File file) {
        if (file.isDirectory()) {
            for (File f : file.listFiles()) {
                deleteFile(f);
            }
        } else {
            if (file.isFile()) {
                file.delete();
            }
        }
        file.delete();
    }

    private static Path compress(String zipName, Path destDir, List<Path> path) throws IOException {
        Path destPath = Files.createFile(destDir.resolve(zipName));
        try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destPath.toFile()))) {
            for (Path p : path) {
                String fileName = p.getFileName().toString();
                ZipEntry entry = new ZipEntry(fileName);
                out.putNextEntry(entry);
                out.write(Files.readAllBytes(p));
            }
        }
        return destPath;
    }

    public static String getValue(String key, String language) {
        Resource res = resourceMap.get(language);
        if (res == null) {
            return null;
        }
        try (Scanner scanner = new Scanner(res.getInputStream())) {
            while (scanner.hasNextLine()) {
                String line = StringUtils.trim(scanner.nextLine());
                if (StringUtils.isNotBlank(line) && !StringUtils.startsWith(language, "#")) {
                    String[] array = StringUtils.split(line, "=");
                    String prop = StringUtils.trim(array[0]);
                    if (StringUtils.equals(key, prop)) {
                        return StringUtils.trim(array[1]);
                    }
                }
            }
            return null;
        } catch (IOException e) {
            log.error("根据Key和Language获取国际化资源错误", e);
            return null;
        }
    }
}
